package com.atguigu.gmall.item.controller;


import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@RestController
public class RedissonLockTestController {


    ReentrantLock lock = new ReentrantLock();
    private String data = "";

    @Autowired
    RedissonClient redissonClient;

    //闭锁(CountDownLatch)
    @GetMapping("/shenlong")
    public String shenlong() throws InterruptedException {
        RCountDownLatch longzhu = redissonClient.getCountDownLatch("longzhu");
        longzhu.trySetCount(7); //准备好数量

        longzhu.await(); //等待任务完成
        return "神龙出来了.....";
    }

    @GetMapping("/longzhu")
    public String shouji() throws InterruptedException {
        RCountDownLatch longzhu = redissonClient.getCountDownLatch("longzhu");

        longzhu.countDown();//数量减1
        return "收集到1颗";
    }


    //信号量（Semaphore）

    @GetMapping("/initpark")
    public String initpark() throws InterruptedException {
        RSemaphore semaphore = redissonClient.getSemaphore("wuhanchechang");
        semaphore.trySetPermits(5);

        return "停车场准备就绪：共【"+semaphore.availablePermits()+"】 车位";
    }

    @GetMapping("/park")
    public String park() throws InterruptedException {
        RSemaphore semaphore = redissonClient.getSemaphore("wuhanchechang");

        semaphore.acquire(); //需要一个信号
        return "停车成功";
    }

    @GetMapping("/go")
    public String go(){
        RSemaphore semaphore = redissonClient.getSemaphore("wuhanchechang");
        semaphore.release();

        int permits = semaphore.availablePermits();
        return "剩余："+permits+"车位";
    }



    // 读写锁（ReadWriteLock）
    //只要写锁已经存在的情况下，做任何事情都得等。 写-写、写-读（等写完成）
    // 读-写（还等等读）
    // 读-读（不用等）
    @GetMapping("/write")
    public String  writeLock() throws InterruptedException {
        RReadWriteLock rwlock = redissonClient.getReadWriteLock("rwlock");
        RLock wLock = rwlock.writeLock();
        wLock.lock(); //加写锁
        System.out.println("正在更新.....");
        data = UUID.randomUUID().toString();
        TimeUnit.SECONDS.sleep(10);
        wLock.unlock();
        return "修改后的值："+data;
    }

    @GetMapping("/read")
    public String readLock() throws InterruptedException {
        RReadWriteLock rwlock = redissonClient.getReadWriteLock("rwlock");
        RLock rLock = rwlock.readLock();
        rLock.lock(); //加读锁
        System.out.println("正在读取中....");
        TimeUnit.SECONDS.sleep(10);
        rLock.unlock(); //解锁
        return "读到的值："+data;
    }




    @GetMapping("/hello/lock")
    public String helloWithRedissonLock() throws InterruptedException {

        //1、得到一个分布式锁。参数传入“锁名字” ，名字一样就是同一把锁
        RLock mylock = redissonClient.getLock("mylock");
        //2、加分布式锁
        mylock.lock(); //阻塞式等待 //可以自动续期; 锁默认30s，业务期间每隔10s，续满30s
        System.out.println("hello...");
        TimeUnit.SECONDS.sleep(30);
        mylock.unlock();  //解锁

        return "ok";
    }


    public String helloWithLocalLockBingqieLockbuzhu() {
        lock.lock();
        System.out.println("hello...");
        try {
            TimeUnit.SECONDS.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        lock.unlock();
        return "ok";
    }

}
